﻿using Microsoft.AspNetCore.SignalR;

using PLCS.Application.Contracts.EquipmentApp;
using PLCS.Application.Contracts.EquipmentApp.Dtos;
using PLCS.Application.EquipmentApp.Hubs;
using PLCS.Domain.Equipments;
using PLCS.Domain.Shared.Equipments;
using PLCS.Domain.Shared.Stations;
using PLCS.Domain.Stations;
using PLCS.SocialHttpClient.AGV;

using Volo.Abp.Application.Dtos;

namespace PLCS.Application.EquipmentApp;

public class EquipmentAppService : CrudAppService<Equipment, EquipmentDto, Guid, PagedResultRequestDto, EquipmentEditDto>, IEquipmentAppService
{
    private readonly IEquipmentRepository _equipmentRepository;
    private readonly AGVSocialService _aGVSocialService;
    private readonly IHubContext<FrameHub> _hubcontext;
    private readonly IStationRepository _stationRepository;

    public EquipmentAppService(IEquipmentRepository equipmentRepository, AGVSocialService aGVSocialService, IHubContext<FrameHub> hubcontext, IStationRepository stationRepository) : base(equipmentRepository)
    {
        _equipmentRepository = equipmentRepository;
        _aGVSocialService = aGVSocialService;
        _hubcontext = hubcontext;
        _stationRepository = stationRepository;
    }

    public async Task<EquipmentDto> GetBySNoAsync(string no)
    {
        var model = await _equipmentRepository.FindAsync(x => x.EquNum == no);
        Check.NotNull(model, no, $"设备‘{no}’不存在");
        return ObjectMapper.Map<Equipment, EquipmentDto>(model);
    }

    public async Task InsertListAsync(IEnumerable<EquipmentEditDto> equipments)
    {
        Check.NotNull(equipments, "设备集合");
        if (!equipments.Any())
            throw new Exception("集合不能为空");
        var list = ObjectMapper.Map<IEnumerable<EquipmentEditDto>, IEnumerable<Equipment>>(equipments);

        await Repository.InsertManyAsync(list);
    }

    public async Task UpdateAsync(EquipmentEditDto input)
    {
        var entity = await GetEntityByIdAsync(input.Id);
        await MapToEntityAsync(input, entity);
        await Repository.UpdateAsync(entity, autoSave: true);
    }

    public async Task DeleteAllAsync()
    {
        await _equipmentRepository.DeleteAllAsync();
    }

    public async Task<PagedResultDto<EquipmentDto>> GetListBySearchAsync(PagedResultRequestDto input, string? equipmentNo, string? equipmentType)
    {
        await CheckGetListPolicyAsync();

        var query = await CreateFilteredQueryAsync(input);

        query = query.OrderBy(x => x.EquNum).ThenBy(x => x.Plc_Index);
        query = query.WhereIf(!string.IsNullOrEmpty(equipmentNo), x => x.EquNum == equipmentNo)
            .WhereIf(!string.IsNullOrEmpty(equipmentType), x => x.EquType == (EquipmentType)Enum.Parse(typeof(EquipmentType), equipmentType));
        var totalCount = await AsyncExecuter.CountAsync(query);

        query = ApplyPaging(query, input);

        var entities = await AsyncExecuter.ToListAsync(query);
        var entityDtos = await MapToGetListOutputDtosAsync(entities);

        return new PagedResultDto<EquipmentDto>(
            totalCount,
            entityDtos
        );
    }

    public async Task Test(string equipmentNo, string rowGoods, string column)
    {
        await _hubcontext.Clients.All.SendAsync("ChangeCranePosition", equipmentNo, rowGoods, column);
    }

    public async Task Test2(string stationNo, YesNo yesNo)
    {
        var station = await _stationRepository.GetStationByNumAsync(stationNo);
        if (station.HaveStatus != yesNo)
        {
            station.ChangeHaveStatus(yesNo);
            await _stationRepository.UpdateAsync(station);
        }
    }

    public async Task Test3(string equipmentNo, DeviceStatus yesNo)
    {
        var equipment = await _equipmentRepository.GetByEquipmentNoAsync(equipmentNo);
        if (equipment.Status != yesNo)
        {
            equipment.Status = (yesNo);
            await _equipmentRepository.UpdateAsync(equipment);
            await _hubcontext.Clients.All.SendAsync("ChangeEquipmentStatus", equipmentNo, yesNo);
        }
    }
}